﻿/*
 * Programer: JR Padfield
 * Description: Handles personal player character.
 * Version: 1
 * Date: 12/17/13 * 
 */

using Microsoft.Xna.Framework;
using TheWorldLibrary.TileEngine;
using TheWorldLibrary.Input;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using TheWorldLibrary.Sprites;
using TheWorldLibrary.Characters;
using TheWorld.Networking;
using TheWorld.Global;

namespace TheWorld.Components
{
    public class Player
    {
        #region Field Region

        Camera camera;
        Client gameRef;
        readonly Character character;

        #endregion

        #region Property Region

        public Camera Camera
        {
            get { return camera; }
            set { camera = value; }
        }

        public AnimatedSprite Sprite
        {
            get { return character.Sprite; }
        }

        public Character Character
        {
            get { return character; }
        }

        #endregion

        #region Constructor Region

        public Player(Game game, Character character)
        {
            gameRef = (Client)game;
            camera = new Camera(gameRef.ScreenRectangle);
            this.character = character;
        }

        public Player()
        {

        }

        #endregion

        #region Method Region

        public void Update(GameTime gameTime)
        {
            camera.Update(gameTime);
            Sprite.Update(gameTime);

            #region Local Player Movement
            
            if (InputHandler.KeyReleased(Keys.PageUp) ||
                InputHandler.ButtonReleased(Buttons.LeftShoulder, PlayerIndex.One))
            {
                camera.ZoomIn();
                if (camera.CameraMode == CameraMode.Follow)
                    camera.LockToSprite(Sprite);
            }
            else if (InputHandler.KeyReleased(Keys.PageDown) ||
                InputHandler.ButtonReleased(Buttons.RightShoulder, PlayerIndex.One))
            {
                camera.ZoomOut();
                if (camera.CameraMode == CameraMode.Follow)
                    camera.LockToSprite(Sprite);
            }

            Vector2 motion = new Vector2();

            if (InputHandler.KeyDown(Keys.W) ||
                InputHandler.ButtonDown(Buttons.LeftThumbstickUp, PlayerIndex.One))
            {
                // Check for blocked tile
                if (Mapping.Instance.CheckBlockedTile((int)Sprite.Position.X /32, (int)(Sprite.Position.Y / 32) - 1) == false)
                {
                    Sprite.CurrentAnimation = AnimationKey.Up;
                    motion.Y = -1;
                }
            }
            else if (InputHandler.KeyDown(Keys.S) ||
                InputHandler.ButtonDown(Buttons.LeftThumbstickDown, PlayerIndex.One))
            {
                Sprite.CurrentAnimation = AnimationKey.Down;
                motion.Y = 1;
            }

            if (InputHandler.KeyDown(Keys.A) ||
                InputHandler.ButtonDown(Buttons.LeftThumbstickLeft, PlayerIndex.One))
            {
                Sprite.CurrentAnimation = AnimationKey.Left;
                motion.X = -1;
            }
            else if (InputHandler.KeyDown(Keys.D) ||
                InputHandler.ButtonDown(Buttons.LeftThumbstickRight, PlayerIndex.One))
            {
                Sprite.CurrentAnimation = AnimationKey.Right;
                motion.X = 1;
            }

            if (motion != Vector2.Zero)
            {
                
                motion.Normalize();

                Sprite.Position += motion * Sprite.Speed * (float)gameTime.ElapsedGameTime.TotalSeconds;
                
                Sprite.IsAnimating = true;
                // Send the movement update
                ClientTcp.Instance.SendPlayerMove((int)Sprite.CurrentAnimation,Sprite.Position.X, Sprite.Position.Y);
                Sprite.LockToMap();

                if (camera.CameraMode == CameraMode.Follow)
                    camera.LockToSprite(Sprite);
            }
            else
            {
                Sprite.IsAnimating = false;
            }

            if (InputHandler.KeyReleased(Keys.F) ||
                InputHandler.ButtonReleased(Buttons.RightStick, PlayerIndex.One))
            {
                camera.ToggleCameraMode();
                if (camera.CameraMode == CameraMode.Follow)
                    camera.LockToSprite(Sprite);
            }

            if (camera.CameraMode != CameraMode.Follow)
            {
                if (InputHandler.KeyReleased(Keys.C) ||
                    InputHandler.ButtonReleased(Buttons.LeftStick, PlayerIndex.One))
                {
                    camera.LockToSprite(Sprite);
                }
            }

            #endregion

            foreach (Character player in Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters)
            {
                if (player == null)
                {
                    continue;
                }
                if (player.Entity.EntityMap == Mapping.Instance.Worlds.CurrentLevel)
                {
                    player.Update(gameTime);
                }
            }

        }

        public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            character.Draw(gameTime, spriteBatch);

            foreach (Character player in Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters)
            {
                if (player == null)
                {
                    continue;
                }
                if (player.Entity.EntityMap == Mapping.Instance.Worlds.CurrentLevel)
                {
                    player.Draw(gameTime, spriteBatch);
                }
            }
        }

        public void UpdatePlayerMovement(AnimationKey animationKey, float x, float y, int playerIndex)
        {
            Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Sprite.Position = new Vector2(x, y);

            switch (animationKey)
            {
                case (AnimationKey.Down):
                    Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Sprite.CurrentAnimation = AnimationKey.Down;
                    break;
                case (AnimationKey.Left):
                    Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Sprite.CurrentAnimation = AnimationKey.Left;
                    break;
                case (AnimationKey.Right):
                    Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Sprite.CurrentAnimation = AnimationKey.Right;
                    break;
                case (AnimationKey.Up):
                    Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Sprite.CurrentAnimation = AnimationKey.Up;
                    break;
            }

            #region Check if going off screen

            if (Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Sprite.Position.X / 32 <= 0)
            {
                // Do not go off screen...
                return;
            }

            if (Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Sprite.Position.X / 32 >= Mapping.Instance.MaxWidth)
            {
                // Do not go off screen...
                return;
            }            

            #endregion

            Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Sprite.IsAnimating = true; 

            Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Sprite.Update(Static._gameTime);

            Mapping.Instance.Worlds.Levels[Mapping.Instance.Worlds.CurrentLevel].Characters[playerIndex].Sprite.IsAnimating = false;
            
        }

        #endregion
    }
}
